package cc.wd.demo.blockchain.model;

import com.alibaba.fastjson.JSON;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.Objects;

/**
 * @author wudi
 * @date 2018/8/29
 */
public class BlockChain implements Serializable {
    private static final long serialVersionUID = -3687610367063168087L;

    private LinkedList<Block> blockChain = new LinkedList<>();

    private BlockChain() {
    }

    public void printChain() {
        String blockChainJson = JSON.toJSONString(blockChain, true);
        System.out.println(blockChainJson);
    }

    public Block addAndValid(String data) {
        Block add = add(data);
        if (!chainValid()) {
            throw new RuntimeException("incorrect chain");
        }
        return add;
    }

    public Block add(String data) {
        Block block;
        if (blockChain.isEmpty()) {
            block = new Block(data, "0");
        } else {
            block = new Block(data, blockChain.getLast().getHash());
        }
        blockChain.add(block);
        return block;
    }

    public boolean chainValid() {
        int size = blockChain.size();
        if (size < 2) {
            return true;
        }
        // 从第二个开始验证
        for (int i = 1; i < size; i++) {
            Block currentBlock = blockChain.get(i);
            String rightHash = currentBlock.calculateHash();
            if (!Objects.equals(currentBlock.getHash(), rightHash)) {
                return false;
            }
            Block previousBlock = blockChain.get(i - 1);
            if (!Objects.equals(currentBlock.getPreviousHash(), previousBlock.getHash())) {
                return false;
            }
        }
        return true;
    }


    public static BlockChain getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private static class InstanceHolder {
        static final BlockChain INSTANCE = new BlockChain();
    }

}
